﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace QT.Windows.Shell
{
    /// <summary>
    /// AeroGlass窗体类
    /// </summary>
    public partial class GlassForm : Form
    {
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

        #region properties

        /// <summary>
        /// 透明Aero对应的颜色，设置为该颜色的空间将呈现为Aero效果
        /// </summary>
        public static Color AeroColor = SystemColors.Control;

        #endregion

        /// <summary>
        /// GlassForm
        /// </summary>
        public GlassForm()
        {
            InitializeComponent();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture(); //释放鼠标捕捉
                //发送左键点击的消息至该窗体(标题栏)
                SendMessage(Handle, 0xA1, 0x02, 0);
            }
        }

        #region operations

        /// <summary>
        /// Makes the background of current window transparent
        /// </summary>
        public void SetAeroGlassTransparency()
        {
            this.BackColor = Color.Transparent;
        }

        /// <summary>
        /// Excludes a Control from the AeroGlass frame.
        /// </summary>
        /// <param name="control">The control to exclude.</param>
        /// <remarks>Many non-WPF rendered controls (i.e., the ExplorerBrowser control) will not 
        /// render properly on top of an AeroGlass frame. </remarks>
        public void ExcludeControlFromAeroGlass(Control control)
        {
            if (control == null) { throw new ArgumentNullException("control"); }

            if (SafeNativeMethods.DwmIsCompositionEnabled())
            {
                Rectangle clientScreen = this.RectangleToScreen(this.ClientRectangle);
                Rectangle controlScreen = control.RectangleToScreen(control.ClientRectangle);

                Margins margins = new Margins();
                margins.LeftWidth = controlScreen.Left - clientScreen.Left;
                margins.RightWidth = clientScreen.Right - controlScreen.Right;
                margins.TopHeight = controlScreen.Top - clientScreen.Top;
                margins.BottomHeight = clientScreen.Bottom - controlScreen.Bottom;

                // Extend the Frame into client area
                SafeNativeMethods.DwmExtendFrameIntoClientArea(Handle, ref margins);
            }
        }

        /// <summary>
        /// Resets the AeroGlass exclusion area.
        /// </summary>
        public void ResetAeroGlass()
        {
            if (this.Handle != IntPtr.Zero)
            {
                Margins margins = new Margins(true);
                SafeNativeMethods.DwmExtendFrameIntoClientArea(this.Handle, ref margins);
            }
        }

        #endregion

        #region implementation
        /// <summary>
        /// Catches the DWM messages to this window and fires the appropriate event.
        /// </summary>
        /// <param name="m"></param>

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (System.Environment.OSVersion.Version.Major >= 6)
            {
                if (SafeNativeMethods.DwmIsCompositionEnabled())
                {
                    if (m.Msg == DWMMessages.WM_DWMCOMPOSITIONCHANGED || m.Msg == DWMMessages.WM_DWMNCRENDERINGCHANGED || m.Msg == DWMMessages.WM_CREATE)
                    {
                        ResetAeroGlass();
                        AeroColor = Color.FromArgb(164, 212, 211);
                        this.TransparencyKey = AeroColor;
                    }
                }
                else
                {
                    if (this.Handle == SafeNativeMethods.GetActiveWindow()) AeroColor = SystemColors.GradientActiveCaption; 
                    else AeroColor = SystemColors.GradientInactiveCaption;

                    this.AllowTransparency = false;
                }

                this.BackColor = AeroColor;
            }

            base.WndProc(ref m);
        }

        #endregion
    }
}
